home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utilmus / mod2smp.lha / source / mix.c < prev    next >
C/C++ Source or Header  |  1996-01-26  |  28KB  |  1,049 lines

  1. #define MAXIM  0x10000
  2. #define VBLVAL 70938
  3. #define VBLVALNTSC 71591
  4. #define CIAVAL 1773447
  5. #define CIAVALNTSC 1789772
  6.  
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<string.h>
  10. #include<proto/exec.h>
  11. #include<exec/memory.h>
  12. #include<proto/dos.h>
  13. #include<proto/exec.h>
  14. #include<proto/intuition.h>
  15. #include<proto/gadtools.h>
  16. #include<proto/reqtools.h>
  17. #include<proto/graphics.h>
  18. #include<devices/audio.h>
  19. #include<libraries/reqtools.h>
  20. #include<thom/thomdos.h>
  21. #include"mix_rev.h"
  22. #include"gadtools.h"
  23.  
  24. char ver[]=VERSTAG;
  25.  
  26. #define ABOUTTXT "Mod2Samp v0.78g\nby\nHali/Union\n\nGUI by Thom/Union"
  27.  
  28. // prototypy
  29. void main(int,char **);
  30. ULONG    mixer(struct kupa);
  31. void adresysampli(BYTE *,struct sampel *,UWORD);
  32. void HandleMainWnd(void);
  33. void Work(void);
  34. void RequestOK(char *);
  35. void RequestAbout(void);
  36. void PrintNote(ULONG);
  37. void LoadModule(char *);
  38. void SaveSample(char *);
  39. void FreeMemory(void);
  40. void Status(char *);
  41. BOOL OpenAudio(void);
  42. void CloseAudio(void);
  43. void Play(void);
  44. void adresysampli(BYTE *,struct sampel *,UWORD);
  45. UWORD policzpatterny(BYTE *);
  46. void SetDefault(APTR);
  47. void SetTitle(void);
  48. WORD    calculate_pom(WORD,WORD,ULONG,ULONG,UBYTE);
  49. WORD    findperiod(WORD,BYTE,BYTE);
  50.  
  51. struct notes
  52. {
  53.     char a[4];
  54. };
  55.  
  56. WORD  periodtab[16][12*3]={
  57.     { 856,808,762,720,678,640,604,570,538,508,480,453,    // Tuning 0, Normal
  58.       428,404,381,360,339,320,302,285,269,254,240,226,
  59.       214,202,190,180,170,160,151,143,135,127,120,113},
  60.     { 850,802,757,715,674,637,601,567,535,505,477,450,    // Tuning 1
  61.       425,401,379,357,337,318,300,284,268,253,239,225,
  62.       213,201,189,179,169,159,150,142,134,126,119,113},
  63.     { 844,796,752,709,670,632,597,563,532,502,474,447,    // Tuning 2
  64.       422,398,376,355,335,316,298,282,266,251,237,224,
  65.       211,199,188,177,167,158,149,141,133,125,118,112},
  66.     { 838,791,746,704,665,628,592,559,528,498,470,444,    // Tuning 3
  67.       419,395,373,352,332,314,296,280,264,249,235,222,
  68.       209,198,187,176,166,157,148,140,132,125,118,111},
  69.     { 832,785,741,699,660,623,588,555,524,495,467,441,    // Tuning 4
  70.       416,392,370,350,330,312,294,278,262,247,233,220,
  71.       208,196,185,175,165,156,147,139,131,124,117,110},
  72.     { 826,779,736,694,655,619,584,551,520,491,463,437,    // Tuning 5
  73.       413,390,368,347,328,309,292,276,260,245,232,219,
  74.       206,195,184,174,164,155,146,138,130,123,116,109},
  75.     { 820,774,730,689,651,614,580,547,516,487,460,434,    // Tuning 6
  76.       410,387,365,345,325,307,290,274,258,244,230,217,
  77.       205,193,183,172,163,154,145,137,129,122,115,109},
  78.     { 814,768,725,684,646,610,575,543,513,484,457,431,    // Tuning 7
  79.       407,384,363,342,323,305,288,272,256,242,228,216,
  80.       204,192,181,171,161,152,144,136,128,121,114,108},
  81.     { 907,856,808,762,720,678,640,604,570,538,508,480,    // Tuning -8
  82.       453,428,404,381,360,339,320,302,285,269,254,240,
  83.       226,214,202,190,180,170,160,151,143,135,127,120},
  84.     { 900,850,802,757,715,675,636,601,567,535,505,477,    // Tuning -7
  85.       450,425,401,379,357,337,318,300,284,268,253,238,
  86.       225,212,200,189,179,169,159,150,142,134,126,119},
  87.     { 894,844,796,752,709,670,632,597,563,532,502,474,    // Tuning -6
  88.       447,422,398,376,355,335,316,298,282,266,251,237,
  89.       223,211,199,188,177,167,158,149,141,133,125,118},
  90.     { 887,838,791,746,704,665,628,592,559,528,498,470,    // Tuning -5
  91.       444,419,395,373,352,332,314,296,280,264,249,235,
  92.       222,209,198,187,176,166,157,148,140,132,125,118},
  93.     { 881,832,785,741,699,660,623,588,555,524,494,467,    // Tuning -4
  94.       441,416,392,370,350,330,312,294,278,262,247,233,
  95.       220,208,196,185,175,165,156,147,139,131,123,117},
  96.     { 875,826,779,736,694,655,619,584,551,520,491,463,    // Tuning -3
  97.       437,413,390,368,347,328,309,292,276,260,245,232,
  98.       219,206,195,184,174,164,155,146,138,130,123,116},
  99.     { 868,820,774,730,689,651,614,580,547,516,487,460,    // Tuning -2
  100.       434,410,387,365,345,325,307,290,274,258,244,230,
  101.       217,205,193,183,172,163,154,145,137,129,122,115},
  102.     { 862,814,768,725,684,646,610,575,543,513,484,457,    // Tuning -1
  103.       431,407,384,363,342,323,305,288,272,256,242,228,
  104.       216,203,192,181,171,161,152,144,136,128,121,114}};
  105.  
  106. struct    kupa {                // user interface
  107.     UBYTE    modstrt;
  108.     UBYTE    modstop;
  109.     UBYTE    speed;
  110.     UBYTE    patt;
  111.     WORD    destperd;
  112.     UBYTE    volume;
  113.     UBYTE    ciaspeed;
  114.     UBYTE    ciaon;
  115.     UBYTE    ntscon;
  116.     UBYTE    resampling;
  117.     UBYTE    sustain;
  118.     };
  119. struct  sampel {            // opis sampla
  120.     UBYTE    volume;
  121.     BYTE    *smpstrt;
  122.     UWORD    smpstop;
  123.     UWORD    repeat;
  124.     UWORD    repeatlen;
  125.     BYTE    finetune;
  126.     };
  127.  
  128. char name[108],loadname[108],savename[108],BORING[]="Boring...",defmod[108],defsmp[108];
  129. BOOL running=TRUE,playing=FALSE,mixed=FALSE;
  130. UBYTE    whichannel[] = { 1,2,4,8 },*chipptr=NULL;
  131. ULONG class,code,modlen,smplen,device,oldlen,kick;
  132. APTR modptr=0,smpptr=0;
  133. BPTR modhandle,smphandle;
  134. struct IOAudio *AudioIO=NULL;
  135. struct MsgPort *AudioMP=NULL;
  136. struct IntuiMessage *message;
  137. struct Library *ReqToolsBase;
  138. struct DiskObject *icon;
  139. struct rtFileRequester *file_req;
  140. struct rtFileRequester *sfile_req;
  141. struct notes notes[]=
  142. {
  143.     "C-1","C#1","D-1","D#1","E-1","F-1","F#1","G-1","G#1","A-1","A#1","B-1",
  144.     "C-2","C#2","D-2","D#2","E-2","F-2","F#2","G-2","G#2","A-2","A#2","B-2",
  145.     "C-3","C#3","D-3","D#3","E-3","F-3","F#3","G-3","G#3","A-3","A#3","B-3",
  146. };
  147. struct kupa sinfo={0,31,6,0,214,50,125,1,0};
  148. extern struct Library *SysBase;
  149.  
  150. void main(int argc,char *argv[])
  151. {
  152.     kick=SysBase->lib_Version;
  153.  
  154.     if(kick>35)
  155.     {
  156.         if(ReqToolsBase=OpenLibrary("reqtools.library",0))
  157.         {
  158.             if(!(icon=TTGetOurIcon(WBenchMsg))) icon=GetDiskObject(argv[0]);
  159.             if(icon)
  160.             {
  161.                 strcpy(defmod,TTString(icon,"MODULE","PROGDIR:"));
  162.                 strcpy(defsmp,TTString(icon,"SAMPLE","PROGDIR:"));
  163.                 TTFreeOurIcon(icon);
  164.             }
  165.             if(file_req=rtAllocRequest(RT_FILEREQ,NULL))
  166.             {
  167.                 if(sfile_req=rtAllocRequest(RT_FILEREQ,NULL))
  168.                 {
  169.                     rtChangeReqAttr( file_req,RTFI_Dir,defmod);
  170.                     rtChangeReqAttr(sfile_req,RTFI_Dir,defsmp);
  171.                     if(OpenAudio())
  172.                     {
  173.                         if(!SetupScreen())
  174.                         {
  175.                             if(!OpenMainWindow())
  176.                             {
  177.                                 PrintNote(24);
  178.                                 while(running)
  179.                                 {
  180.                                     Wait(1<<MainWnd->UserPort->mp_SigBit);
  181.                                     HandleMainWnd();
  182.                                 }
  183.                                 CloseMainWindow();
  184.                             }
  185.                             else RequestOK("Can't open window");
  186.                             CloseDownScreen();
  187.                         }
  188.                         else RequestOK("Can't setup screen");
  189.                         CloseAudio();
  190.                     }
  191.                     else RequestOK("Can't allocate audio channel");
  192.                     rtFreeRequest(sfile_req);
  193.                 }
  194.                 else RequestOK("Can't allocate requester");
  195.                 rtFreeRequest(file_req);
  196.             }
  197.             else RequestOK("Can't allocate requester");
  198.             CloseLibrary(ReqToolsBase);
  199.         }
  200.         else RequestOK("Can't open reqtools.library");
  201.         FreeMemory();
  202.     }
  203. }
  204.  
  205. void HandleMainWnd()
  206. {
  207.     APTR windowlock;
  208.     struct Gadget *gadget;
  209.     struct MenuItem *item;
  210.  
  211.     while(message=GT_GetIMsg(MainWnd->UserPort))
  212.     {
  213.         class  = message->Class;
  214.         code   = message->Code;
  215.         gadget = (struct Gadget *)message->IAddress;
  216.         GT_ReplyIMsg(message);
  217.         switch(class)
  218.         {
  219.             case IDCMP_CLOSEWINDOW:
  220.                 running=FALSE;
  221.                 break;
  222.             case IDCMP_MENUPICK:
  223.                 while(code!=MENUNULL) 
  224.                 {
  225.                     item = (struct MenuItem *) ItemAddress(MainMenus,code);
  226.                     switch(ITEMNUM(code))
  227.                     {
  228.                         case 0:    // About
  229.                             RequestAbout();
  230.                             break;
  231.                         case 2: // Quit
  232.                             running=FALSE;
  233.                             break;
  234.                     }
  235.                     code=item->NextSelect;
  236.                 }
  237.                 break;
  238.             case IDCMP_MOUSEMOVE:
  239.                 switch(gadget->GadgetID)
  240.                 {
  241.                     case GD_PATTERN:
  242.                         sinfo.patt=code;
  243.                         break;
  244.                     case GD_START:
  245.                         sinfo.modstrt=code;
  246.                         break;
  247.                     case GD_END:
  248.                         sinfo.modstop=code;
  249.                         break;
  250.                     case GD_CIASPEED:
  251.                         sinfo.ciaspeed=code;
  252.                         break;
  253.                     case GD_VBLSPEED:
  254.                         sinfo.speed=code;
  255.                         break;
  256.                     case GD_FREQUENCY:
  257.                         PrintNote(code);
  258.                         sinfo.destperd=periodtab[0][code];
  259.                         break;
  260.                     case GD_VOLUME:
  261.                         sinfo.volume=code;
  262.                         break;
  263.                 }
  264.                 break;
  265.             case IDCMP_GADGETUP:
  266.                 switch(gadget->GadgetID)
  267.                 {
  268.                     case GD_QUIT:
  269.                         running=FALSE;
  270.                         break;
  271.                     case GD_LOAD:
  272.                         windowlock=rtLockWindow(MainWnd);
  273.                         rtSetWaitPointer(MainWnd);
  274.                         if(rtFileRequest(file_req,name,"Select file...",
  275.                                 RT_Window,            MainWnd,
  276.                                 RT_Underscore,    '_',
  277.                                 RT_ReqPos,            REQPOS_CENTERSCR,
  278.                                 RTFI_Height,        256,
  279.                                 RTFI_OkText,        "_Ok...",
  280.                                 TAG_DONE))
  281.                         {
  282.                             strcpy(loadname,file_req->Dir);
  283.                             if(loadname[strlen(loadname)>0])
  284.                                 if(loadname[strlen(loadname)-1]!=':') strcat(loadname,"/");
  285.                             strcat(loadname,name);
  286.                             Status("Loading...");
  287.                             LoadModule(loadname);
  288.                             SetDefault(modptr);
  289.                             Status(BORING);
  290.                         }
  291.                         rtUnlockWindow(MainWnd,windowlock);
  292.                         break;
  293.                     case GD_SAVE:
  294.                         windowlock=rtLockWindow(MainWnd);
  295.                         rtSetWaitPointer(MainWnd);
  296.                         if(rtFileRequest(sfile_req,name,"Select file...",
  297.                                 RT_Window,            MainWnd,
  298.                                 RT_Underscore,    '_',
  299.                                 RT_ReqPos,            REQPOS_CENTERSCR,
  300.                                 RTFI_Flags,            FREQF_SAVE,
  301.                                 RTFI_Height,        256,
  302.                                 RTFI_OkText,        "_Ok...",
  303.                                 TAG_DONE))
  304.                         {
  305.                             strcpy(savename,sfile_req->Dir);
  306.                             if(savename[strlen(savename)>0])
  307.                                 if(savename[strlen(savename)-1]!=':') strcat(savename,"/");
  308.                             strcat(savename,name);
  309.                             Status("Loading...");
  310.                             SaveSample(savename);
  311.                             Status(BORING);
  312.                         }
  313.                         rtUnlockWindow(MainWnd,windowlock);
  314.                         break;
  315.                     case GD_PLAY:            // disabled
  316. //                        windowlock=rtLockWindow(MainWnd);
  317. //                        rtSetWaitPointer(MainWnd);
  318.                         Status("Playing...");
  319.                         Play();
  320.                         Status(BORING);
  321.                         SetTitle();
  322. //                        rtUnlockWindow(MainWnd,windowlock);
  323.                         break;
  324.                     case GD_MIX:
  325.                         windowlock=rtLockWindow(MainWnd);
  326.                         rtSetWaitPointer(MainWnd);
  327.                         Status("Working...");
  328.                         Work();
  329.                         Status(BORING);
  330.                         rtUnlockWindow(MainWnd,windowlock);
  331.                         break;
  332.                     case GD_CIA:
  333.                         sinfo.ntscon=code;
  334.                         break;
  335.                     case GD_INTERRUPT:
  336.                         if(code) sinfo.ciaon=0;
  337.                         else sinfo.ciaon=1;
  338.                         break;
  339.                     case GD_RESAMPLING:
  340.                         sinfo.resampling=(UBYTE) code;
  341.                         break;
  342.                     case GD_PATTERN:
  343.                         sinfo.patt=code;
  344.                         break;
  345.                     case GD_START:
  346.                         sinfo.modstrt=code;
  347.                         break;
  348.                     case GD_END:
  349.                         sinfo.modstop=code;
  350.                         break;
  351.                     case GD_CIASPEED:
  352.                         sinfo.ciaspeed=code;
  353.                         break;
  354.                     case GD_VBLSPEED:
  355.                         sinfo.speed=code;
  356.                         break;
  357.                     case GD_FREQUENCY:
  358.                         PrintNote(code);
  359.                         sinfo.destperd=periodtab[0][code];
  360.                         break;
  361.                     case GD_VOLUME:
  362.                         sinfo.volume=code;
  363.                         break;
  364.                     case GD_SUSTAIN:
  365.                         sinfo.sustain=code;
  366.                         break;
  367.                 }
  368.                 break;
  369.         }
  370.     }
  371. }
  372.  
  373. void PrintNote(ULONG code)
  374. {
  375.     char notetxt[4];
  376.  
  377.     sprintf(notetxt,"%s",notes[code].a);
  378.     GT_SetGadgetAttrs(MainGadgets[GD_PITCHTEXT],MainWnd,NULL,GTTX_Text,notetxt,TAG_DONE);
  379. }
  380.  
  381. void Work()
  382. {
  383.     int a;
  384.     ULONG *ptr;
  385.  
  386.     if(modptr)
  387.     {
  388. //        printf(" Module length : %i \n",modlen);
  389. //        printf(" Module name   : %s \n",modptr);
  390. //        printf(" Module mark   : %s \n",(ULONG)modptr+1080);
  391. //        memset(smpptr,0,2*MAXIM);
  392.         ptr=smpptr;
  393.         for(a=0;a<MAXIM/2;a++) ptr[a]=0L;
  394.         smplen=mixer(sinfo);
  395.     }
  396.     else
  397.         RequestOK("No module in memory");
  398. }
  399.  
  400.  
  401.  
  402.  
  403. /**********************************\
  404. *                                  *
  405. *               Mixer              *
  406. *                                  *
  407. \**********************************/
  408.  
  409. #define    FIND_ANYTHING(ptr)  (*((ULONG *)(ptr)))
  410. #define    FIND_PERIOD(ptr)    (*((UWORD *)ptr)&0x0fff)
  411. #define    FIND_SMPNUMBER(ptr) (((*ptr)&(0xf0))+((*(ptr+2))>>4))
  412. #define    FIND_EFFECT(ptr)    ((*(ptr+2))&0x0f)
  413. #define    FIND_PARAMETR(ptr)  (*(ptr+3))
  414.  
  415.  
  416. ULONG    mixer(sinfo)
  417. struct    kupa sinfo;
  418. {
  419.     char    text[20];
  420.     BYTE    *module;            // adres moduîu
  421.     WORD    *fromword;          // pointery do zamiany z word'ow na
  422.     BYTE    *tobyte;            // bajty
  423.     ULONG    len;                // koncowa dlugosc sampla
  424.     ULONG    h,i,j,k;            // zmienne do organizacji petli
  425.     UWORD    hipatt=0;           // tu bedzie ilosc pattern'ów
  426.     ULONG    ilenapoz;           // ile sampla wygenerowac
  427.                                 // do nastepnej pozycji
  428.     WORD    *ptr2smp;           // pointery do generowania
  429.     WORD    *ptr2smppom;        // zmiksowanego sampla ( w word'ach)
  430.     UBYTE    *ptr2mod;           // pointer do przesuwania sie 
  431.                                 // po module
  432.     UBYTE    speed;              // aktualna predkosc
  433.     UBYTE    ciaspeed;
  434.     UBYTE    ilepozycji;         // ile pozycji do zrobienia
  435.     UWORD    pomoc;
  436.     WORD    pom;
  437.     WORD    probka0,probka1;
  438.     UBYTE    sust;
  439.  
  440.     struct    sampel smp[32];     // tablica pointerow do sampli 
  441.     struct    canal {             // co sie dzieje w kanale
  442.         BYTE    nrsmp;       // numer odgrywanego sampla
  443.         BYTE    volume;      // gîoônoôê sampla
  444.         WORD    period;      // period
  445.         ULONG    jump;
  446.         ULONG    jumppos;
  447.         UWORD    smppos;
  448.         BYTE    *smpstrt;
  449.         UWORD    smpstop;
  450.         UWORD    smprepeat;
  451.         UWORD    smprepeatlen;
  452.         BYTE    volslide;    // do komendy - Axx
  453.         UBYTE    last9;       // do komendy - 9xx
  454.         UBYTE    actE9;       // do komendy - E9x
  455.         UBYTE    notecut;     // do komendy - ECx
  456.         WORD    trgetperd;   // do komendy - 3xx
  457.         WORD    toneslide;   // ----------------
  458.         WORD    lasttrget;   // ----------------
  459.         WORD    lasttonesl;  // ----------------
  460.         UBYTE    arpeggio;    // do komendy - 0xx
  461.         WORD    saveperd;    // ----------------
  462.         };
  463.     struct    canal chan[4]={{0,0,0,0,0,0,0,0},
  464.                            {0,0,0,0,0,0,0,0},
  465.                            {0,0,0,0,0,0,0,0},
  466.                            {0,0,0,0,0,0,0,0}};
  467.     struct    line {
  468.         ULONG    anything;
  469.         WORD    period;
  470.         UBYTE    smpnumber;
  471.         UBYTE    effect;
  472.         UBYTE    parametr;
  473.     };
  474.     struct    line    trackline[4];
  475.  
  476.  
  477.     sust=sinfo.sustain;
  478.     module=modptr;
  479.     ptr2smp=smpptr;
  480.     hipatt=policzpatterny(module);
  481.     adresysampli(module,smp,hipatt);
  482.     speed=sinfo.speed;
  483.     ciaspeed=sinfo.ciaspeed;
  484.     if(sust){
  485.       ilepozycji=sinfo.modstop+1;
  486.       ptr2mod=module+1084+1024*sinfo.patt; // ustawienie sie na odpowiednia pozycje
  487.     }
  488.     else{
  489.       ilepozycji=sinfo.modstop-sinfo.modstrt+1;
  490.       ptr2mod=module+1084+1024*sinfo.patt+16*sinfo.modstrt; // ustawienie sie na odpowiednia pozycje
  491.     }
  492.  
  493. //    if(debug)  printf("   Destination Period = %i\n",sinfo.destperd);
  494.  
  495.  
  496. //    printf("   Wow! There will be %i positions. \n    >",ilepozycji);
  497.     for(h=0;h<=(ilepozycji-1);h++){
  498.  
  499.       if((sust)&&(h>=sinfo.modstrt)) sust=0;
  500.  
  501.       for(i=0;i<=3;i++){
  502.         trackline[i].anything  = (ULONG)FIND_ANYTHING(ptr2mod);
  503.         trackline[i].period    = (WORD)FIND_PERIOD(ptr2mod);
  504.         trackline[i].smpnumber = (UBYTE)FIND_SMPNUMBER(ptr2mod);
  505.         trackline[i].effect    = (UBYTE)FIND_EFFECT(ptr2mod);
  506.         trackline[i].parametr  = (UBYTE)FIND_PARAMETR(ptr2mod);
  507.         ptr2mod=ptr2mod+4;
  508.       }
  509.  
  510. //      if(debug){
  511. //        printf("\n"); 
  512. //        for(i=0;i<=3;i++){
  513. //          if(trackline[i].period) printf("  J-4");
  514. //          else printf("  ---");
  515. //          printf("%2x%1x%2x",trackline[i].smpnumber,trackline[i].effect,trackline[i].parametr);
  516. //        }
  517. //      }
  518.  
  519.  
  520.  
  521.  
  522.       for(i=0;i<=3;i++){
  523.         chan[i].volslide=0;
  524.         chan[i].actE9=0;
  525.         chan[i].toneslide=0;
  526.         chan[i].arpeggio=0;
  527.         chan[i].saveperd=0;
  528.         if(trackline[i].smpnumber){
  529.            chan[i].nrsmp=trackline[i].smpnumber;
  530.           chan[i].volume=smp[chan[i].nrsmp].volume;
  531.         }
  532.         pomoc=0;
  533.         if(trackline[i].effect==0x03) pomoc=1;
  534.         if(trackline[i].effect==0x05) pomoc=1;
  535.         if( (trackline[i].period)&&(pomoc==0) ){
  536.           chan[i].period=trackline[i].period;
  537.           chan[i].trgetperd=0;
  538.           if( smp[chan[i].nrsmp].finetune)
  539.             chan[i].period = findperiod( chan[i].period, smp[chan[i].nrsmp].finetune,0);
  540.           chan[i].smpstrt=smp[chan[i].nrsmp].smpstrt;
  541.           chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
  542.           chan[i].smprepeat=smp[chan[i].nrsmp].repeat;
  543.           chan[i].smprepeatlen=smp[chan[i].nrsmp].repeatlen;
  544.           chan[i].smppos=0;
  545.           chan[i].jumppos=0;
  546.         }
  547.         switch(trackline[i].effect){
  548.           case 0x0f:
  549.             if( (sinfo.ciaon)&&(trackline[i].parametr>0x1f) )
  550.               ciaspeed=trackline[i].parametr;
  551.             else
  552.               speed=trackline[i].parametr;
  553.             break;
  554.           case 0x0e:
  555.             switch(trackline[i].parametr>>4){
  556.               case 0x09:
  557.                 chan[i].actE9=trackline[i].parametr&0x0f;
  558.               break;
  559.               case 0x0a:
  560.                 chan[i].volume+=trackline[i].parametr&0x0f;
  561.               break;
  562.               case 0x0b:
  563.                 chan[i].volume-=trackline[i].parametr&0x0f;
  564.               break;
  565.               case 0x0c:
  566.                 chan[i].notecut=(trackline[i].parametr&0x0f)+1;
  567.               break;
  568.               case 0x02:
  569.                 chan[i].period+=trackline[i].parametr&0x0f;
  570.                 if( chan[i].period>findperiod(856,smp[chan[i].nrsmp].finetune,0) )
  571.                   chan[i].period=findperiod(856,smp[chan[i].nrsmp].finetune,0);
  572.               break;
  573.               case 0x01:
  574.                 chan[i].period-=trackline[i].parametr&0x0f;
  575.                 if( chan[i].period<findperiod(113,smp[chan[i].nrsmp].finetune,0) )
  576.                   chan[i].period=findperiod(113,smp[chan[i].nrsmp].finetune,0);
  577.               break;
  578.             }
  579.             break;
  580.           case 0x0c:
  581.             chan[i].volume=trackline[i].parametr;
  582.             break;
  583.           case 0x0a:
  584.             if( (trackline[i].parametr)&0xf0)
  585.               chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
  586.             else
  587.               chan[i].volslide=-trackline[i].parametr;
  588.             break;
  589.           case 0x09:
  590.             if(trackline[i].parametr)
  591.               chan[i].last9=trackline[i].parametr;
  592.             pomoc=((UWORD)chan[i].last9)<<8;
  593.             if(pomoc>(chan[i].smpstop))
  594.               chan[i].smppos=chan[i].smprepeat;
  595.             else
  596.               chan[i].smppos=pomoc;
  597.             chan[i].jumppos=0;
  598.             break;
  599.           case 0x05:
  600.             if( (trackline[i].parametr)&0xf0)
  601.               chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
  602.             else
  603.               chan[i].volslide=-trackline[i].parametr;
  604.             if(trackline[i].period){
  605.               chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
  606.               chan[i].lasttrget=chan[i].trgetperd;
  607.             }
  608.             else{
  609.               chan[i].trgetperd=chan[i].lasttrget;
  610.             }
  611.             if( chan[i].period>chan[i].trgetperd )
  612.               chan[i].toneslide=-chan[i].lasttonesl;
  613.             else
  614.               chan[i].toneslide=chan[i].lasttonesl;
  615.             if(chan[i].trgetperd==0) chan[i].toneslide=0;
  616.             break;
  617.           case 0x03:
  618.             if(trackline[i].period){
  619.               chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
  620.               chan[i].lasttrget=chan[i].trgetperd;
  621.             }
  622.             else{
  623.               chan[i].trgetperd=chan[i].lasttrget;
  624.             }
  625.             chan[i].lasttonesl=trackline[i].parametr;
  626.             if( chan[i].period>chan[i].trgetperd )
  627.               chan[i].toneslide=-trackline[i].parametr;
  628.             else
  629.               chan[i].toneslide=trackline[i].parametr;
  630.             if(chan[i].trgetperd==0) chan[i].toneslide=0;
  631.             break;
  632.           case 0x02:
  633.             chan[i].trgetperd=findperiod(856,smp[chan[i].nrsmp].finetune,0);
  634.             chan[i].toneslide=trackline[i].parametr;
  635.             break;
  636.           case 0x01:
  637.             chan[i].trgetperd=findperiod(113,smp[chan[i].nrsmp].finetune,0);
  638.             chan[i].toneslide=-trackline[i].parametr;
  639.             break;
  640.           case 0x00:
  641.             if(trackline[i].parametr){
  642.               chan[i].arpeggio=trackline[i].parametr;
  643.               chan[i].saveperd=chan[i].period;
  644.             }
  645.             break;
  646.         } 
  647.       }
  648.  
  649.       // ile probek
  650.       if(sinfo.ciaon){
  651.         if(sinfo.ntscon)
  652.           ilenapoz=((CIAVALNTSC*5)/ciaspeed)/sinfo.destperd;
  653.         else
  654.           ilenapoz=((CIAVAL*5)/ciaspeed)/sinfo.destperd;
  655.       }
  656.       else{  
  657.         if(sinfo.ntscon)
  658.           ilenapoz=VBLVALNTSC/sinfo.destperd;
  659.         else
  660.           ilenapoz=VBLVAL/sinfo.destperd;
  661.       }
  662.  
  663.       // mixowanie
  664.       for(i=0;i<=3;i++){
  665.       ptr2smppom=ptr2smp;
  666.       //printf("\n");
  667.         for(k=0;k<=(speed-1);k++){
  668.           // comman E9x retrig note
  669.           if(chan[i].actE9){
  670.             if( (k-(k/chan[i].actE9)*chan[i].actE9)==0 ){
  671.               chan[i].smppos=0;
  672.               chan[i].jumppos=0;
  673.               chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
  674.             }
  675.           }
  676.           // comman ECx note cut
  677.           if(chan[i].notecut){
  678.             if( k==(chan[i].notecut-1) ){
  679.               chan[i].volume=0;
  680.             }
  681.           }
  682.           // command Axx volsliding
  683.           if((chan[i].volslide)&&(k!=0)){
  684.             chan[i].volume=chan[i].volume+chan[i].volslide;
  685.             if(chan[i].volume<0) chan[i].volume=0;
  686.             if(chan[i].volume>64) chan[i].volume=64;
  687.           }
  688.           // command 3xx tone sliding
  689.           if((chan[i].toneslide)&&(k!=0)){
  690.             //printf("!");
  691.             chan[i].period+=chan[i].toneslide;
  692.             if(chan[i].toneslide<0){
  693.               if(chan[i].period<chan[i].trgetperd)
  694.                 chan[i].period=chan[i].trgetperd;
  695.             }
  696.             else{
  697.               if(chan[i].period>chan[i].trgetperd)
  698.                 chan[i].period=chan[i].trgetperd;
  699.             }
  700.           }
  701.           // command 0xx arpeggio
  702.           if(chan[i].arpeggio){
  703.                 switch( k-(k/3)*3 ){
  704.               case 2:
  705.                 chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio&0x0f);
  706.                 break;
  707.               case 1:
  708.                 chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio>>4);
  709.                 break;
  710.               case 0:
  711.                 chan[i].period=chan[i].saveperd;
  712.                 break;
  713.             }
  714.           }
  715.  
  716.           //printf(" %i",chan[i].period);
  717.  
  718.           if(chan[i].period!=0)
  719.             chan[i].jump=(((ULONG)sinfo.destperd)<<16)/chan[i].period;
  720.           else
  721.             chan[i].jump=0;
  722.  
  723.           // generowanie sampla
  724.           for(j=0;j<=ilenapoz;j++){
  725.             if((ULONG)ptr2smppom>=(ULONG)smpptr+MAXIM*2) break; // jesli przekroczymy bufor to stop
  726.  
  727.             chan[i].smppos+=(UWORD)(chan[i].jumppos>>16);
  728.             chan[i].jumppos=chan[i].jumppos&0xffff;
  729.  
  730.             if(chan[i].smppos>=chan[i].smpstop){
  731.                chan[i].smppos=chan[i].smprepeat+(chan[i].smppos-chan[i].smpstop);
  732.                chan[i].smpstop=chan[i].smprepeat+chan[i].smprepeatlen;
  733.             }
  734.  
  735.             probka0=*(chan[i].smppos+chan[i].smpstrt);
  736.             probka1=*(chan[i].smppos+chan[i].smpstrt+1);
  737.             if((chan[i].smppos+1)>=chan[i].smpstop){
  738.                 probka1=*(chan[i].smprepeat+chan[i].smpstrt);
  739.             }
  740.  
  741.             pom=calculate_pom(probka0,probka1,chan[i].jumppos,chan[i].jump,sinfo.resampling);
  742.  
  743.             if(sust==0){
  744.               *ptr2smppom+=(pom*chan[i].volume)/64;
  745.               ptr2smppom++;
  746.             }
  747.             chan[i].jumppos+=chan[i].jump;
  748.           }
  749.         }
  750.         if(chan[i].saveperd){
  751.           chan[i].period=chan[i].saveperd;
  752.         }
  753.       }
  754.       ptr2smp=ptr2smppom;
  755. //      printf("*");
  756.     }
  757. //    printf("\n");
  758.  
  759.     // obcinanie
  760.     len=((ULONG)ptr2smp-(ULONG)smpptr)/2;
  761.     fromword=smpptr;
  762.     tobyte=smpptr;
  763.     for(i=0;i<=len;i++){
  764.       pom=((*fromword++)*sinfo.volume)/100;
  765.       if(pom>127) pom=127;
  766.       if(pom<-128) pom=-128;
  767.       *tobyte++=pom;
  768.       if((i>>10)<<10==i)
  769.       {
  770.             sprintf(text,"%i",i);
  771.             Status(text);
  772.         }
  773. //        printf("\r   hmm ... : %i ",i);
  774.     }
  775. //    printf("\r   OK it's: %i \n",i);
  776.     sprintf(text,"%i",i);
  777.     Status(text);
  778.  
  779.     mixed=TRUE;
  780.  
  781.     return(len);
  782. }
  783.  
  784. WORD    findperiod(mainperiod,finetune,index)
  785. WORD    mainperiod;
  786. BYTE    finetune;
  787. BYTE    index;
  788. {
  789.     UWORD    i;
  790.  
  791.     for(i=0;i<=12*3;i++)
  792.       if(mainperiod==periodtab[0][i]) break;
  793.     i=i+index;
  794.     if(i>=12*3) return(0);
  795.  
  796.     return(periodtab[finetune][i]);
  797. }
  798.  
  799. WORD    calculate_pom(sample0,sample1,jumppos,jump,method)
  800. WORD    sample0;
  801. WORD    sample1;
  802. ULONG    jumppos;
  803. ULONG    jump;
  804. UBYTE    method;
  805. {
  806.     WORD    a;
  807.     WORD    i;
  808.     ULONG    myjumppos;
  809.  
  810.     if(jump==0)
  811.       return(0);
  812.  
  813.     myjumppos=jumppos;
  814.  
  815.     if(method){
  816.       for(i=1;(jump)<(0x10000/(i+1));i++);
  817.       //printf("i= %i\n",i);
  818.       if(i>1){
  819.         if(jumppos<((0x10000/i)*(i-1)))
  820.           return(sample0);
  821.         else{
  822.           myjumppos=(jumppos-((0x10000/i)*(i-1)))*i;
  823.         }
  824.       }
  825.     }
  826.  
  827.     a=sample1-sample0;
  828.     a=(WORD)(((LONG)myjumppos*a)>>16);
  829.     a=a+sample0;
  830.     return(a);
  831. }
  832.  
  833.  
  834. UWORD    policzpatterny(module)
  835. BYTE    *module;
  836. {
  837.     UWORD    pomoc;
  838.     UWORD    i;
  839.     UWORD    hipat=0;
  840.  
  841.     for(i=0;i<=127;i++){
  842.       pomoc=*((UBYTE *)(module+952+i));
  843.       hipat=(hipat>pomoc)?hipat:pomoc;
  844.     }
  845.     hipat++;
  846.     return(hipat);
  847. }
  848.  
  849.  
  850.  
  851. void    adresysampli(module,smp,hipatt)
  852. BYTE    *module;
  853. struct    sampel smp[];        // tablica pointerow do sampli 
  854. UWORD    hipatt;
  855. {
  856.     UWORD    i;
  857.     UWORD    pomoc;
  858.  
  859.     smp[1].smpstrt=module+1084+1024*hipatt;
  860.     smp[1].smpstop=(*((UWORD *)(module+42)))*2;
  861.     smp[1].volume=*((UBYTE *)(module+45));
  862.     smp[1].repeat=(*((UWORD *)(module+46)))*2;
  863.     smp[1].repeatlen=(*((UWORD *)(module+48)))*2;
  864.     smp[1].finetune=*((UBYTE *)(module+44));
  865.     for(i=2;i<=31;i++){
  866.       pomoc=*((UWORD *)(module+42+30*(i-2)));
  867.       smp[i].smpstrt=smp[i-1].smpstrt+pomoc*2;
  868.       smp[i].smpstop=(*((UWORD *)(module+42+30*(i-1))))*2;
  869.       smp[i].volume=*((UBYTE *)(module+45+30*(i-1)));
  870.       smp[i].repeat=(*((UWORD *)(module+46+30*(i-1))))*2;
  871.       smp[i].repeatlen=(*((UWORD *)(module+48+30*(i-1))))*2;
  872.       smp[i].finetune=*((UBYTE *)(module+44+30*(i-1)));
  873.       if(smp[i].repeat)  smp[i].smpstop=smp[i].repeat+smp[i].repeatlen;
  874.     }
  875.  
  876. //    if(debug){
  877. //      for(i=1;i<=8;i++)
  878. //        printf(" %2i.  vol %-2x   strt $%-6x   stop $%-4x %-5i repeat $%-4x repeatlen $%-4x \n",i,smp[i].volume,smp[i].smpstrt,smp[i].smpstop,smp[i].smpstop,smp[i].repeat,smp[i].repeatlen);
  879. //    }
  880. }
  881.  
  882. /*------------------------------------------------------------------------------*/
  883.  
  884. void RequestOK(char *what)
  885. {
  886.     APTR windowlock;
  887.  
  888.     windowlock=rtLockWindow(MainWnd);
  889.     rtSetWaitPointer(MainWnd);
  890.     rtEZRequestTags(what,"_Ok",NULL,NULL,RT_Underscore,'_',RT_Window,MainWnd,TAG_DONE);
  891.     rtUnlockWindow(MainWnd,windowlock);
  892. }
  893.  
  894. void RequestAbout()
  895. {
  896.     APTR windowlock;
  897.  
  898.     windowlock=rtLockWindow(MainWnd);
  899.     rtSetWaitPointer(MainWnd);
  900.     rtEZRequestTags(ABOUTTXT,"_Ok",NULL,NULL,RT_Underscore,'_',
  901.                     RT_Window,MainWnd,
  902.                     RTEZ_Flags,EZREQF_CENTERTEXT,
  903.                     TAG_DONE);
  904.     rtUnlockWindow(MainWnd,windowlock);
  905. }
  906.  
  907. void LoadModule(char *filename)
  908. {
  909.     FreeMemory();
  910.     if(modhandle=Open(filename,MODE_OLDFILE))
  911.     {
  912.         Seek(modhandle,0,OFFSET_END);
  913.         modlen=Seek(modhandle,0,OFFSET_BEGINNING);
  914.         if(modptr=AllocMem(modlen,MEMF_PUBLIC))
  915.         {
  916.             Read(modhandle,modptr,modlen);
  917.             if(*((ULONG *)((ULONG)modptr+1080))!=*((ULONG *)"M.K."))
  918.             {
  919.                 RequestOK("This is not a ProTracker module");
  920.                 FreeMem(modptr,modlen);
  921.                 modptr=0;
  922.             }
  923.             if(!(smpptr=AllocMem(MAXIM*2,MEMF_CLEAR|MEMF_PUBLIC)))
  924.             {
  925.                 RequestOK("Not enough memory to allocate sample buffer.");
  926.                 FreeMem(smpptr,MAXIM*2);
  927.                 modptr=0;
  928.             }
  929.             mixed=FALSE;
  930.         }
  931.         else
  932.             RequestOK("Not enough memory");
  933.         Close(modhandle);
  934.     }
  935.     else
  936.         RequestOK("Can't open module");
  937. }
  938.  
  939. void SaveSample(char *filename)
  940. {
  941.     if(modptr && smpptr)
  942.     {
  943.         if(smphandle=Open(filename,MODE_NEWFILE))
  944.         {
  945.             if(Write(smphandle,smpptr,smplen)==-1)
  946.             {
  947.               RequestOK("Can't save file.");
  948.             }
  949.             Close(smphandle);
  950.         }
  951.         else
  952.             RequestOK("Can't open file to save");
  953.     }
  954. }
  955.  
  956. void FreeMemory()
  957. {
  958.     if(modptr) FreeMem(modptr,modlen);
  959.     modptr=0;
  960.     if(smpptr) FreeMem(smpptr,MAXIM*2);
  961.     smpptr=0;
  962. }
  963.  
  964. void Status(char *text)
  965. {
  966.     GT_SetGadgetAttrs(MainGadgets[GD_STATUS],MainWnd,NULL,GTTX_Text,text,TAG_DONE);
  967. }
  968.  
  969. BOOL OpenAudio()
  970. {
  971.     if(AudioMP = CreatePort(0,0))
  972.     {
  973.         if(AudioIO=(struct IOAudio *)CreateExtIO(AudioMP,sizeof(struct IOAudio)))
  974.         {
  975.             AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE;
  976.             AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 50;
  977.             AudioIO->ioa_AllocKey = 0;
  978.             AudioIO->ioa_Data     = whichannel;
  979.             AudioIO->ioa_Length   = sizeof(whichannel);
  980.             if(!(device=OpenDevice(AUDIONAME,0L, (struct IORequest *) AudioIO ,0L)))
  981.             {
  982.                 return(1);
  983.             }
  984.         }
  985.     }
  986.     return(0);
  987. }
  988.  
  989. void CloseAudio()
  990. {
  991.     if (device == 0) CloseDevice((struct IORequest *) AudioIO);
  992.     if (AudioIO != 0) DeleteExtIO((struct IORequest *)AudioIO);
  993.     if (AudioMP != 0) DeletePort(AudioMP);
  994. }
  995.  
  996. void Play()
  997. {
  998.     if(playing)
  999.     {
  1000.         AbortIO((struct IORequest *)AudioIO);
  1001.         playing=FALSE;
  1002.         if(chipptr) FreeMem(chipptr,oldlen);
  1003.         chipptr=NULL;
  1004.     }
  1005.     else
  1006.     {
  1007.         if(mixed)
  1008.         {
  1009.             if(smpptr)
  1010.             {
  1011.                 if(chipptr=AllocMem(smplen,MEMF_CHIP))
  1012.                 {
  1013.                     playing=TRUE;
  1014.                     oldlen=smplen;
  1015.                     CopyMem(smpptr,(APTR) chipptr,smplen);
  1016.                     AudioIO->ioa_Request.io_Command=CMD_WRITE;
  1017.                     AudioIO->ioa_Request.io_Flags  =ADIOF_PERVOL;
  1018.                     AudioIO->ioa_Data  =chipptr;
  1019.                     AudioIO->ioa_Length=smplen;
  1020.                     AudioIO->ioa_Period=sinfo.destperd;
  1021.                     AudioIO->ioa_Volume=64;
  1022.                     AudioIO->ioa_Cycles=0;
  1023.                     BeginIO((struct IORequest *)AudioIO);
  1024. //                    WaitIO((struct IORequest *)AudioIO);
  1025. //                    AbortIO((struct IORequest *)AudioIO);
  1026. //                    FreeMem(chipptr,smplen);
  1027.                 }
  1028.             }
  1029.         }
  1030.         else
  1031.             RequestOK("No sample in memory");
  1032.     }
  1033. }
  1034.  
  1035. void SetDefault(APTR modptr)
  1036. {
  1037.     UWORD patts;
  1038.  
  1039.     patts=policzpatterny(modptr);
  1040.     GT_SetGadgetAttrs(MainGadgets[GD_PATTERN],MainWnd,NULL,GTSL_Max,(ULONG)patts-1,TAG_DONE);
  1041. }
  1042.  
  1043. void SetTitle()
  1044. {
  1045. //    if(playing)    MainGadgets[GD_PLAY]->GadgetText="Stop";
  1046. //    else MainGadgets[GD_PLAY]->GadgetText="Play";
  1047. //    GT_RefreshWindow(MainWnd,NULL);
  1048. }
  1049.